package vns.server;

import java.util.ArrayList;
import java.util.List;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import vns.client.service.PermService;
import vns.server.domain.ObjectProperty;
import vns.server.domain.Perm;
import vns.server.domain.Role;
import vns.shared.ObjectPropertyDTO;
import vns.shared.PermDTO;
import vns.shared.RoleDTO;
import vns.server.domain.ObjectType;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

@SuppressWarnings("serial")
public class PermServiceImpl extends RemoteServiceServlet implements
		PermService {

	@Override
	public PermDTO Create(PermDTO permDTO) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Perm action = null;
		try {
			action = new Perm(permDTO);
			pm.makePersistent(action);
		} finally {
			pm.close();
		}
		return action.toDTO();
	}

	@Override
	public boolean Remove(Key id) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			Perm action = pm.getObjectById(Perm.class, id);
			if (action != null) {
				pm.deletePersistent(pm.getObjectById(Perm.class, id));
			}
		} finally {
			pm.close();
		}
		return true;
	}

	@Override
	public PermDTO Loadbyid(Key id) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		PermDTO actionDTO = null;
		try {
			Perm action = pm.getObjectById(Perm.class, id);
			actionDTO = action.toDTO();
		} finally {
			pm.close();
		}
		return actionDTO;
	}

	@Override
	public PermDTO Update(PermDTO permDTO) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Perm action = null;
		try {
			action = pm.getObjectById(Perm.class, permDTO.getId());
			action.updatefromDTO(permDTO);
		} finally {
			pm.close();
		}

		return action.toDTO();
	}

	@SuppressWarnings("unchecked")
	@Override
	public ArrayList<PermDTO> Loadall(RoleDTO roleDTO) {
		ArrayList<PermDTO> listactionDTO = new ArrayList<PermDTO>();
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Query q = pm.newQuery(Perm.class);
		q.setFilter("roleID==:role");
		try {
			List<Perm> actionset = (List<Perm>) q.execute(KeyFactory
					.keyToString(roleDTO.getId()));
			for (Perm action : actionset) {
				PermDTO temp = action.toDTO();
				ObjectProperty op = pm.getObjectById(ObjectProperty.class,
						KeyFactory.stringToKey(action.getPropertyID()));
				temp.setPropertyName(op.getName());
				ObjectType ot = pm.getObjectById(ObjectType.class,
						KeyFactory.stringToKey(op.getObjecttype()));
				temp.setObjectTypeName(ot.getName());
				temp.setRolename(roleDTO.getName());
				listactionDTO.add(temp);
			}
		} finally {
			pm.close();
		}
		return listactionDTO;
	}

	@SuppressWarnings("unchecked")
	@Override
	public ArrayList<PermDTO> Loadall(ObjectPropertyDTO opropertyDTO) {
		ArrayList<PermDTO> listactionDTO = new ArrayList<PermDTO>();
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Query q = pm.newQuery(Perm.class);
		q.setFilter("roleID==:role");
		try {
			List<Perm> actionset = (List<Perm>) q.execute(KeyFactory
					.keyToString(opropertyDTO.getId()));
			for (Perm action : actionset) {
				PermDTO temp = action.toDTO();
				Role role = pm.getObjectById(Role.class,
						KeyFactory.stringToKey(action.getRoleID()));
				temp.setPropertyName(role.getName());
				temp.setObjectTypeName(opropertyDTO.getObjtypename());
				temp.setPropertyName(opropertyDTO.getName());
				listactionDTO.add(temp);
			}
		} finally {
			pm.close();
		}
		return listactionDTO;
	}

	@Override
	public void Updateall(List<PermDTO> listNew) {
		List<PermDTO> listOld = this.LoadAll();
		for (PermDTO element : listNew) {
			if (!containInList(listOld, element)) {
				element = this.Create(element);
			} else {
				this.Update(element);
			}
		}
		for (PermDTO element : listOld) {
			if (!containInList(listNew, element)) {
				this.Remove(element.getId());
			}
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<PermDTO> LoadAll() {
		List<PermDTO> permDTO = new ArrayList<PermDTO>();
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Query q = pm.newQuery(Perm.class);
		try {
			List<Perm> res = (List<Perm>) q.execute();
			for (Perm actiontype : res) {
				permDTO.add(actiontype.toDTO());
			}
		} finally {
			pm.close();
		}
		return permDTO;

	}

	private boolean containInList(List<PermDTO> list, PermDTO element) {
		if (element.getId() == null)
			return false;
		for (PermDTO optDTO : list) {
			if (optDTO.getId().equals(element.getId()))
				return true;
		}
		return false;
	}
}
